// WaitGroup 让某个线程处于等待状态
#include <workflow/WFFacilities.h>
// WFHttpServer.h 包含server类的设计
#include <workflow/WFHttpServer.h>
#include <iostream>
#include <string>
#include <signal.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
using std::cout;
using std::string;
struct SeriesContext{
    string name;
    string password;
    protocol::HttpResponse *resp; // 决定了回复给客户端的内容
};
static WFFacilities::WaitGroup waitGroup(1);
void sigHandler(int signum){
    cout << "done!\n";
    waitGroup.done();
}
void redisCallback(WFRedisTask * redisTask){
    // 获取redis的执行结果
    protocol::RedisValue result;
    protocol::RedisResponse * resp = redisTask->get_resp();
    resp->get_result(result);

    // 访问context
    SeriesContext * context =  static_cast<SeriesContext *>(series_of(redisTask)->get_context());
    if(result.is_string() && result.string_value() == context->password){
        cout << context->name << " success\n";
        context->resp->append_output_body("<html>success</html>");
    }else{
        cout << context->name << " fail\n";
        context->resp->append_output_body("<html>fail</html>");
    }
}
void process(WFHttpTask *serverTask){
    protocol::HttpRequest * req = serverTask->get_req();
    if(string(req->get_method()) == "GET"){
        int fd = open("postform.html",O_RDWR);
        char buf[4096] = {0};
        int len = read(fd,buf,4096);
        protocol::HttpResponse * resp = serverTask->get_resp();
        resp->append_output_body(buf,len);
    }
    else if(string(req->get_method()) == "POST"){
        const void *body;
        size_t size;
        req->get_parsed_body(&body,&size);
        string reqbody = static_cast<const char *>(body);
        string nameKV = reqbody.substr(0,reqbody.find("&"));
        string passwordKV = reqbody.substr(reqbody.find("&")+1);
        string name = nameKV.substr(nameKV.find("=")+1);
        string password = passwordKV.substr(passwordKV.find("=")+1);

        // 申请一片内存空间，用于序列内的任务共享数据
        SeriesContext * context = new SeriesContext;
        context->name = name;
        context->password = password;
        context->resp = serverTask->get_resp();
        series_of(serverTask)->set_context(context);
        // 创建一个redis任务
        WFRedisTask * redisTask = WFTaskFactory::create_redis_task("redis://127.0.0.1:6379",10,redisCallback);
        // hget 57user niqiu
        redisTask->get_req()->set_request("HGET",{"57user",name});
        series_of(serverTask)->push_back(redisTask);
    }

}
int main(){
    signal(SIGINT,sigHandler);
    WFHttpServer server(process);
    if(server.start(12345) == 0){
        waitGroup.wait();
        server.stop();
    }
    else{
        perror("server start failed!");
        return -1;
    }
    cout << "finished!\n"; 
    return 0;
}